OpenGL:Tutorials:Tutorial Framework:Display Lists
__TOC__ What is a display list? Display lists are a way of bundling OpenGL commands for future execution. They can give a performance boost when construction of our objects involves calculation or other slow downs. Once our object data is in the display list, it can be recalled easily and without the calculation that was required to produce it. The other nice aspect of display lists is that they fit in with OpenGL's state system, we can change the texture, color, size or any aspect of the object that isn't explicitly defined in the list. Using Display Lists We use the glGenLists() function to allocate storage for display lists: DListRoot=glGenLists(3); This is similar to generating texture storage except that the lists originate from the returned base point rather than the array used for textures. To access display list n'' we simply call: glCallList(DListRoot+n); To clean up or delete the lists we use: glDeleteLists(DListRoot,3); An Example In our example we are going to create display lists for three objects. These objects will then be displayed with different textures and scale factors to demonstrate the adjustments that are possible due to GL's state system. Our objects are managed by a a similar setup to the particle demo; a structure contains the unique parameters for each object: typedef struct { float xPos,yPos,zPos,Rotate; int TexNum,ObjList; float Red,Green,Blue; float Scale,rVec; }ObjInfo; These parameters are initalised to random values: for(index=0;index An important note here is that scaling our object will scale all our geometery, including normals. This will change the lighting of the polygons. To stop this we use: glEnable(GL_NORMALIZE); Which prevents scaling from changing our normal lengths. So, on to the lists. First, we allocate 3 lists as discussed: DListRoot=glGenLists(3); The actual compilation of the lists can occur anywhere, but here we'll separate it into three functions, '''BuildCube()',BuildDiamond() and BuildStar(). These functions build some simple objects. Looking at the functions, we can see that most of the code is pretty standard OpenGL, we are specifing UV and vertex coords in the usual way. The only difference is that the call to glNewList() means that we are storing the instructions rather than rendering the polygons. glNewList(ListID,GL_COMPILE); // OpenGL code here glEndList(); The GL_COMPILE flag tells OpenGL to store the instructions with no output, if we use GL_COMPILE_AND_EXECUTE the instructions will be stored and displayed. This can be useful for scenes where the geometery is rendered more than once per frame, e.g. when producing reflections. To execute a display list we use the glCallList() function. As previously mentioned, any current states that are not explicitly set in the list will be used when rendering the objects in the list. Because our lists only specify UV coords, not textures, we are able to change the appearance of the objects easily. Our demo looks like this: Files:GLTut7 (DispList).jpg Other things to try with display lists are: * Changing object colors, * Nesting display lists, * Calling multiple lists with glCallLists(). Source Code The source to Render.cpp, compile this demo using the OpenGL Tutorial Framework. #include "Framework.h" #include #include #include "tga.h" const int NUM_OBJ=2000; // Number of Objects // Vector structure typedef struct { float x,y,z; }stVec; // Object Structure typedef struct { float xPos,yPos,zPos,Rotate; int TexNum,ObjList; float Red,Green,Blue; float Scale,rVec; }ObjInfo; // Function declarations bool LoadTexture(char *TexName, GLuint TexHandle); stVec CalcNormal(float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3); void BuildCube(GLuint ListID); void BuildDiamond(GLuint ListID); void BuildStar(GLuint ListID); void Render(void) { GLuint Texture128; // Handles to our textures ObjInfo ObjNUM_OBJ; // Object array GLuint DListRoot; // Display List float Rot=0.0f; // Rotation value for the observer int index; float view_height=600.0f/800.0f; // Allocate all textures in one go glGenTextures(128,Texture); // Setup our screen glViewport(0,0,800,600); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-0.5f,0.5f,-0.5f* view_height,0.5f*view_height, 1.0f, 500.0f); glMatrixMode(GL_MODELVIEW); glClearColor(0.0f,0.0f,0.0f,1.0f); // Enable z-buffer glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glEnable(GL_CULL_FACE); // Prevent scaling operations from affecting normal values glEnable(GL_NORMALIZE); // Load the textures LoadTexture("../Images/Logo.tga",Texture0); LoadTexture("../Images/lightbricks.tga",Texture1); // Allocate 3 display lists DListRoot=glGenLists(3); // Build the display lists BuildCube(DListRoot); BuildDiamond(DListRoot+1); BuildStar(DListRoot+2); // Seed the randomiser srand(time(NULL)); // Init the object parameters for(index=0;index Downloads GLTut7_(Display_Lists).zip - Zip containing Win32 and GLFW source code, texture images and a Win32 Binary.